package com.shaw.mybatisx.session;

import com.shaw.mybatisx.annotation.Select;
import com.shaw.mybatisx.executor.Executor;
import com.shaw.mybatisx.executor.SimpleExecutor;
import com.shaw.mybatisx.plugin.Interceptor;
import com.shaw.mybatisx.plugin.InterceptorChain;
import com.shaw.running.pojo.User;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by asus on 2018/4/1.
 */
public class Configuration {
    public final static Map<String,MapperDate> registMap = new HashMap<>();

    protected final static InterceptorChain interceptorChain = new InterceptorChain();

    private String mapperPath;

    public Configuration(){
        init();
    }

    public Configuration(List<Class> mappers){
        init(mappers);
    }

    public Configuration(List<Class> mappers,List<Interceptor> plugins){
        init(mappers,plugins);
    }

    private void init(){
        MapperDate mapperDate = new MapperDate();
        mapperDate.setSql("select * from user where id = %d");
        mapperDate.setType(User.class);
        mapperDate.setSqlType("select");
        registMap.put("com.shaw.mybatisx.TestMapper.selectByPrimaryKey",mapperDate);
    }

    private void init(List<Class> mappers){
        for(Class clazz:mappers){
            annotationPrasing(clazz);
        }
    }

    private void init(List<Class> mappers,List<Interceptor> plugins){
        //mapper解析
        for(Class mapperClass:mappers){
            annotationPrasing(mapperClass);
        }
        //plugin加入集合
        for(Interceptor pluginClass:plugins){
            interceptorChain.addInterception(pluginClass);
        }
    }

    private void annotationPrasing(Class clazz){
        StringBuilder sb = new StringBuilder();
        sb.append(clazz.getName());
        sb.append(".");
        Method[] methods = clazz.getMethods();
        for(Method method:methods){
            sb.append(method.getName());
            if(method.getAnnotation(Select.class)!=null){
                Select select = method.getAnnotation(Select.class);
                MapperDate mapperDate = new MapperDate();
                mapperDate.setSql(select.value());
                mapperDate.setType(method.getReturnType());
                mapperDate.setSqlType("select");
                registMap.put(sb.toString(),mapperDate);
            }
        }

    }

    public Executor newExecutor(){
        Executor executor = new SimpleExecutor();
        executor= (Executor)interceptorChain.plginAll(executor);
        return executor;
    }

    public class MapperDate<E>{
        private String sql = "";
        private Class<E> type;
        private String sqlType = "select";

        public Class<E> getType() {
            return type;
        }

        public void setType(Class<E> type) {
            this.type = type;
        }

        public void setSql(String sql) {
            this.sql = sql;
        }


        public String getSql() {
            return sql;
        }

        public String getSqlType() {
            return sqlType;
        }

        public void setSqlType(String sqlType) {
            this.sqlType = sqlType;
        }
    }
}
